﻿using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;

namespace ForguncySecurityProviderPackageTool;

public class Program
{
    public static void Main(string[] args)
    {
        if (args.Length < 2)
        {
            Console.WriteLine($"param count：{args.Length} is not correct");
            return;
        }

        var projectPath = args[0];
        if (string.IsNullOrWhiteSpace(projectPath))
        {
            Console.WriteLine("projectPath cannot be null or empty");
            return;
        }

        projectPath = Path.GetFullPath(projectPath);
        Console.WriteLine($"projectPath: {projectPath}");

        var fileName = args[1];
        if (string.IsNullOrWhiteSpace(fileName))
        {
            Console.WriteLine("fileName cannot be null or empty");
            return;
        }

        Console.WriteLine($"fileName: {fileName}");

        var temp = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
        Directory.CreateDirectory(temp);
        try
        {
            // DependenceVersion.json
            File.Copy(Path.Combine(projectPath, "DependenceVersion.json"),
                Path.Combine(temp, "DependenceVersion.json"));
            MakeFileNotReadOnly(Path.Combine(temp, "DependenceVersion.json"));

            // LICENSE.txt
            var licenseFile = Path.Combine(projectPath, "LICENSE.txt");
            if (File.Exists(licenseFile))
            {
                File.Copy(licenseFile,
                    Path.Combine(temp, "LICENSE.txt"));
                MakeFileNotReadOnly(Path.Combine(temp, "LICENSE.txt"));
            }

            // bin/
            CopyFolder(Path.Combine(projectPath, "bin"), Path.Combine(temp));

            var zipFile = Path.Combine(projectPath, "bin", fileName + ".zip");
            if (File.Exists(zipFile))
            {
                MakeFileNotReadOnly(zipFile);
                File.Delete(zipFile);
            }

            ZipFile.CreateFromDirectory(temp, zipFile);
        }
        finally
        {
            Directory.Delete(temp, true);
        }

        Console.WriteLine("Completed!");
    }

    private static void MakeFileNotReadOnly(string fileName)
    {
        if (File.Exists(fileName))
        {
            if ((File.GetAttributes(fileName) & FileAttributes.ReadOnly) == FileAttributes.ReadOnly)
            {
                File.SetAttributes(fileName, File.GetAttributes(fileName) & ~FileAttributes.ReadOnly);
            }
        }
    }

    private static void CopyFolder(string sourcePath, string destinationPath, HashSet<string> skipFiles = null)
    {
        if (!Directory.Exists(destinationPath))
        {
            Directory.CreateDirectory(destinationPath!);
        }

        //Now Create all of the directories
        foreach (var dirPath in Directory.GetDirectories(sourcePath, "*", SearchOption.AllDirectories))
        {
            Directory.CreateDirectory(dirPath.Replace(sourcePath, destinationPath));
        }

        //Copy all the files & Replaces any files with the same name
        foreach (var newPath in Directory.GetFiles(sourcePath, "*.*", SearchOption.AllDirectories))
        {
            if (skipFiles != null)
            {
                if (skipFiles.Contains(Path.GetFileName(newPath)))
                {
                    continue;
                }
            }

            if (Path.GetExtension(newPath) == ".pdb" ||
                Path.GetExtension(newPath) == ".ts" ||
                Path.GetFileName(newPath).ToLower().EndsWith(".js.map") ||
                Path.GetExtension(newPath) == ".zip")
            {
                continue;
            }

            var newFile = newPath.Replace(sourcePath, destinationPath);

            File.Copy(newPath, newFile, true);

            MakeFileNotReadOnly(newFile);
        }
    }
}